[模板]可持久化Trie

2020-02-20
模板

题意

对于序列$\{a_i\}$,支持以下操作:

1.在序列后添加一个数$x$

2.给出$l,r,x$,求出一个$p\in[l,r]$,使得$\oplus_{p\leq i\leq n} a_i\space xor\space x$最大

题解

前缀和,求$a_{l-2}$到$a_{r-1}$异或$x\space xor\space a_{cnt}$的max

调试记录

边界条件没弄好,要先从a[u]继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <cstdio>
#include <algorithm>
const int maxn = 6e5 + 5;
using namespace std;
struct T{
struct A{
int son[2], v, tim;
A(){tim = -1; v = 0;}
}a[maxn * 30]; int tot = 0;
void insert(int u, int v, int x, int dep, int tim){
if (dep == 0){
a[v].v = a[u].v + 1;
a[v].tim = tim;
return;
}
a[v] = a[u]; a[v].v++;
int d = (x >> (dep - 1)) & 1;
insert(a[u].son[d], a[v].son[d] = ++tot, x, dep - 1, tim);
}
int find(int u, int v, int dep, int x){
if (a[v].tim != -1) return a[v].tim;
int d = (x >> (dep - 1)) & 1;
if (a[a[v].son[d ^ 1]].v - a[a[u].son[d ^ 1]].v != 0) return find(a[u].son[d ^ 1], a[v].son[d ^ 1], dep - 1, x);
return find(a[u].son[d], a[v].son[d], dep - 1, x);
}
}t;
int a[maxn], rt[maxn], n, Q, cnt;
int main(){
scanf("%d%d", &n, &Q); t.insert(0, rt[0] = ++t.tot, 0, 20, 0);
for (int i = 1; i <= n; i++){
scanf("%d", a + i); a[i] ^= a[i - 1];
t.insert(rt[i - 1], rt[i] = ++t.tot, a[i], 20, i);
} cnt = n;
while (Q--){
char opt[5]; int l, r, x;
scanf("%s", opt);
if (opt[0] == 'A'){
scanf("%d", &x);
t.insert(rt[cnt], rt[cnt + 1] = ++t.tot, x, 20, cnt + 1);
a[cnt + 1] = x ^ a[cnt]; ++cnt;
}
if (opt[0] == 'Q'){
scanf("%d%d%d", &l, &r, &x);
int pos = t.find(rt[min(0, l - 2)], rt[r - 1], 20, x ^ a[cnt]);
printf("%d\n", (a[pos] ^ x ^ a[cnt]));
}
}
return 0;
}